package com.example.service.impl;

import com.example.service.ThreadPoolExecutorService;
import common.annotations.Inner;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import org.apache.commons.lang3.concurrent.BasicThreadFactory;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @Author Story
 * @Date 2022/3/23 20:02
 * @Version 1.0
 */
@Service
public class ThreadPoolExecutorServiceImpl implements ThreadPoolExecutorService {


    private static final Integer IO_CORE_POOL_SIZE = Runtime.getRuntime().availableProcessors() * 2;
    private static final Integer CPU_CORE_POOL_SIZE = Runtime.getRuntime().availableProcessors();

    private static final Integer MAXIMUM_POOL_IO_SIZE = IO_CORE_POOL_SIZE;
    private static final Integer MAXIMUM_POOL_CPU_SIZE = CPU_CORE_POOL_SIZE;

    @Override
    public ThreadPoolExecutor executeTaskThread(String factoryName, String type) {
        return this.threadPoolHandle(type, factoryName);
    }

    /**
     * 使用线程池执行任务 第一种是 CPU 密集型任务，比如加密、解密、压缩、计算等一系列需要大量耗费 CPU 资源的任务 第二种任务是耗时 IO 型，比如数据库、文件的读写，网络通信等任务，这种任务的特点是并不会特别消耗 CPU 资源，但是 IO 操作很耗时，总体会占用比较多的时间
     *
     * @param coor
     * @return
     */
    @Override
    @Inner
    public ScheduledExecutorService executeScheduledTaskThread(Integer coor) {
        return this.threadTaskPoolHandle(coor);
    }

    /**
     * 创建一个线程工厂
     *
     * @param
     * @return
     */
    @Async
    public ThreadPoolExecutor threadPoolHandle(String type, String factoryName) {
        ThreadFactory factory = r -> new Thread(r, factoryName);
        Integer maxPoolSize = type.equals("0") ? MAXIMUM_POOL_IO_SIZE : MAXIMUM_POOL_CPU_SIZE;
        ThreadPoolExecutor threadPool = new ThreadPoolExecutor(maxPoolSize, maxPoolSize, 3,
                                                               TimeUnit.SECONDS, new ArrayBlockingQueue<>(100), factory, new ThreadPoolExecutor.CallerRunsPolicy());
        threadPool.prestartAllCoreThreads();
        return threadPool;
    }

    /**
     * 创建一个线程工厂
     *
     * @param
     * @return
     */
    public ScheduledExecutorService threadTaskPoolHandle(Integer corePoolSize) {
        ScheduledExecutorService threadPool = new ScheduledThreadPoolExecutor(corePoolSize,
                                                                              new BasicThreadFactory.
                                                                                      Builder().namingPattern("example-schedule-pool-%d").daemon(true).build());
        return threadPool;
    }
}
